const path = require('path');
const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require("./webpack/plugins/CopyWebpackPlugin")
// 尝试使用环境变量，否则使用根路径
const ASSET_PATH = process.env.ASSET_PATH || '';

module.exports = {
    entry: {
        // app: ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&noInfo=true&reload=true',"./src/index.ts"],
        app: ["./src/index.ts"],
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Production',
        }),
        // 这可以帮助我们在代码中安全地使用环境变量
        new webpack.DefinePlugin({
            'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
        }),
        new CopyWebpackPlugin({
            from:"public",
            to:"css",
            ignore:["**/index.html"]
        })
    ],
    output: {
        filename: '[name].bundle.js',
        // 打包生成的chunk名
        chunkFilename: '[name].chunk.js',
        path: path.resolve(__dirname, 'dist'),
        clean: true,
        publicPath: ASSET_PATH,
    },
    optimization:{
        // 只导出exports导出并且使用到的成员（polyfill，它影响全局作用域，并且通常不提供 export），
        // 用于treeshaking的优化，也就是不打包没使用过的模块内容
        usedExports: true,
        // 抽离runtime包
        runtimeChunk: "single",
        // 开发环境压缩需要设置为true，生产环境不需要
        // minimize: true,
        // 拆包处理配置
        splitChunks: {
            chunks: "all",
            // 以下是默认值
            // minSize: 20000, // 分割代码最小的大小
            // minRemainingSize: 0, // 类似于minSize，最后确保提取的文件大小不能为0
            // minChunks: 1, // 至少被引用的次数，满足条件才会代码分割
            // maxAsyncRequests: 30, // 按需加载时并行加载的文件的最大数量
            // maxInitialRequests: 30, // 入口js文件最大并行请求数量
            // enforceSizeThreshold: 50000, // 超过50kb一定会单独打包（此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequests）
            // cacheGroups: { // 组，哪些模块要打包到一个组
            //   defaultVendors: { // 组名
            //     test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块
            //     priority: -10, // 权重（越大越高）
            //     reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块，则它将被重用，而不是生成新的模块
            //   },
            //   default: { // 其他没有写的配置会使用上面的默认值
            //     minChunks: 2, // 这里的minChunks权重更大
            //     priority: -20,
            //     reuseExistingChunk: true,
            //   },
            // },
            // 缓存组，splitChunks就是根据缓存组的配置去进行拆包处理
            cacheGroups: {
                // 将所有的css Chunk提取到一个文件中
                // styles: {
                //     name: "styles",
                //     type: "css/mini-extract",
                //     chunks: "all",
                //     enforce: true,
                // },
                // 将第三方库(library)提取到单独的 vendor chunk 文件中（覆盖掉动态引入的拆包）
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all',
                },
                // default: {
                //     // 其他没有写的配置会使用上面的默认值
                //     minSize: 0, // 我们定义的文件体积太小了，所以要改打包的最小文件体积
                //     minChunks: 2,
                //     priority: -20,
                //     reuseExistingChunk: true,
                // },
            },
        },
    },
    // 解析第三方模块的规则配置
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
        // 引入模块时可以使用路径别名
        alias: {
            "@": path.resolve(__dirname, 'src/'),
        },
    },
    // 解析loader的规则配置
    resolveLoader:{
        // loader的解析位置（用法同resolve）
        modules:[
            "node_modules",
            path.resolve(__dirname, 'webpack/loaders')
        ]
    },
    module:{
        rules:[{
            oneOf:[
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            // 开启缓存，如果JS文件未发生变化，直接使用初次打包后的缓存文件，避免了二次转码，有效提高打包速度。
                            cacheDirectory: true,
                        }
                    }
                },
                {
                    test: /\.tsx?$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            // 开启缓存，如果JS文件未发生变化，直接使用初次打包后的缓存文件，避免了二次转码，有效提高打包速度。
                            cacheDirectory: true,
                        }
                    }
                },
                {
                    test:/\.s?css$/,
                    use:[
                        "style-loader",
                        "css-loader",
                        "sass-loader"
                    ]
                },
                {
                    test: /\.(png|svg|jpg|gif)$/,
                    type: 'asset/resource'
                    // ****目前发现file-loader与css-loader同时使用存在问题，导致css中的背景图片异常
                    // use: [{
                    //     loader: 'url-loader',
                    //     options: {
                    //         name:"[name].[hash:8].[ext]",
                    //         limit: 8 * 1024, // 8k
                    //     }
                    // }]
                },
                {
                    test: /\.(woff|woff2|eot|ttf|otf)$/,
                    type: 'asset/resource'
                },
            ]
        }]
    },
};